package category

import (
	"context"
	tools "mall/common/utils"
	"mall/services/product/rpc/internal/domain/bo"
	"mall/services/product/rpc/internal/mapper"
	"mall/services/product/rpc/internal/mapper/entity"

	"mall/services/product/rpc/internal/svc"
	"mall/services/product/rpc/pb"

	"github.com/zeromicro/go-zero/core/logx"
)

type PageListLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewCategoryPageListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PageListLogic {
	return &PageListLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *PageListLogic) CategoryPageList(in *pb.CategoryPageListDTO) (*pb.CategoryPageListVO, error) {
	// 1.select count
	pageListBO, categoryMapper := l.selectCount(in)
	if pageListBO.Err != nil {
		return nil, pageListBO.Err
	}
	if pageListBO.TotalCount <= 0 {
		return &pb.CategoryPageListVO{PageSize: in.PageSize, CurrentPage: in.PageNum}, nil
	}
	// 2. select list
	selectListCtx, selectListErr := l.selectList(in, pageListBO, categoryMapper)
	if selectListErr != nil {
		return nil, selectListErr
	}
	// 3.return obj
	resp := l.packageObj(in, pageListBO, selectListCtx)
	return resp, nil
}

func (l *PageListLogic) packageObj(in *pb.CategoryPageListDTO, pageListBO bo.CategoryPageListBO,
	selectListCtx []entity.CategoryEntity) *pb.CategoryPageListVO {

	totalCount := pageListBO.TotalCount
	resp := new(pb.CategoryPageListVO)
	pageUtil := tools.NewPageUtil[entity.CategoryEntity](in.PageNum, in.PageNum, int32(totalCount), selectListCtx)
	resp.TotalPage = pageUtil.TotalPage
	resp.HasNextPage = pageUtil.HasNextPage
	resp.CurrentPage = pageUtil.CurrentPage
	resp.TotalCount = pageUtil.TotalCount
	resp.Prev = pageUtil.Prev
	resp.PageSize = in.PageSize
	resp.Next = pageUtil.Next
	records := pageUtil.Records
	var categoryPageArr []*pb.CategoryPageVO
	for _, v := range records {
		p := new(pb.CategoryPageVO)
		p.CategoryId = v.CategoryId
		p.ShopId = v.ShopId
		p.ParentId = v.ParentId
		p.Name = v.Name
		p.Desc = v.Desc
		p.Path = v.Path
		p.Status = int32(v.Status)
		p.Icon = v.Icon
		p.ImgUrl = v.ImgUrl
		p.Level = int32(v.Level)
		p.Seq = int32(v.Seq)
		categoryPageArr = append(categoryPageArr, p)
	}
	resp.Records = categoryPageArr
	return resp
}

func (l *PageListLogic) selectList(in *pb.CategoryPageListDTO, pageListBO bo.CategoryPageListBO,
	categoryMapper *mapper.CategoryMapper) ([]entity.CategoryEntity, error) {

	categoryBO := pageListBO.CategoryBO
	pageSize := in.PageSize
	pageNum := in.PageNum
	startPageIndex := 0
	if pageNum > 1 {
		startPageIndex = int((pageNum - 1) * pageSize)
	}
	categoryBO.PageSize = int(pageSize)
	categoryBO.StartIndex = startPageIndex
	selectListCtx, err := categoryMapper.SelectListCtx(l.svcCtx.DBEngin, categoryBO)
	if err != nil {
		return nil, err
	}
	return selectListCtx, nil
}

func (l *PageListLogic) selectCount(in *pb.CategoryPageListDTO) (bo.CategoryPageListBO, *mapper.CategoryMapper) {
	categoryMapper := mapper.NewCategoryMapper(l.ctx)
	categoryBO := bo.CategoryBO{}
	categoryBO.ShopId = in.ShopId
	categoryBO.NameAllLike = in.CategoryName
	categoryBO.Status = int64(in.Status)
	categoryBO.Level = int64(in.Level)
	selectCountCtx, err := categoryMapper.SelectCountCtx(l.svcCtx.DBEngin, categoryBO)
	if err != nil {
		return bo.CategoryPageListBO{Err: err}, nil
	}
	pageListBO := bo.CategoryPageListBO{TotalCount: selectCountCtx}
	pageListBO.CategoryBO = categoryBO
	return pageListBO, categoryMapper
}
